/*
 * Esta clase debe contener los metodo insert, delete, update y Find conectados a la Interfase.
 * Para ello extiende como super clase Beans, que contiende todos los atributos de la tabla
 * De requerirse algun atributo que no lo contemple Beas, este debe ser creado aquÃ­
 * 
 */
package user.allocation;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.naming.NamingException;
import system.general.Exc;
import system.general.Logged;
import system.general.Message;
import system.general.Persistencia;
import system.general.Label;

/**
 *
 * @author emojica
 */
@ManagedBean(name = "user_allocation")
@RequestScoped
public class Main extends Beans {

    Logged logged;
    private Persistencia persistencia = new Persistencia();
    private Message msg = new Message();
    // private user.login.Find user_allocantionlFind = new user.login.Find();
    //  private List<Beans> user_allocationList = new ArrayList<>();
    private Find user_allocantionlFind = new Find();
    private String sql;
    private Map<String, String> map = new LinkedHashMap<>();
    private Map<Integer, Boolean> checked = new LinkedHashMap<>();
    private Map<Integer, Boolean> caduca = new LinkedHashMap<>();
    private Map<Integer, String> state = new LinkedHashMap<>();
    List<Beans> beansList;
    private List<Beans> tableList = new ArrayList<>();
    private int cant = 0;
    private int dias = 0;
    private Label label = new Label();

    
    public Main() {
        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
        logged = (Logged) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "logged");
    }

    private void load() {
        try {
            //* no requerido 
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    /**
     * MÃ©todo utilizado para INSERTAR O ACTUALIZAR un registro. Para ello
     * requiere que el id del registro haya sido asignado a la variable RecordId
     * del logged. En este caso en particular, el usuario es localizado por el
     * id_persona.
     */
    public void insert() {
        try {
            //se carga el mapa con los valores
            map.clear();
            map.put("id_usuario = " + getId_usuario().toString(), " AND ");
            map.put("id_gps  = " + getId_gps().toString(), " ");

            //Verifica si el registro existe, de lo contrario lo inserta
            if (user_allocantionlFind.byExist(map)) {
                throw new Exc("m5");
            }

            sql = "INSERT INTO public.usuario_gps   (id_gps,id_usuario) "
                    + "VALUES (" + getId_gps() + ",'" + getId_usuario() + "')";

            //Inserta la información del registro
            persistencia.executeUpdate(sql);

            //Localiza el id del registro recien insertado, con la llave única
            // user_allocationList = user_allocantionlFind.byMap(map);

            //Asigna el id del registro insertado a la variable global
            //   logged.setDetailId(user_allocationList.get(0).getId());

            throw new Exc("m1");

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void update() {
        try {
            if (logged.getMasterId() == 0) {
                throw new Exc("m4");
            }
            //Verifica si hay registros seleccionados
            if (logged.getDetailId() == 0) {
                throw new Exc("m6");
            }

            //carga el mapa con los valores
            map.clear();
            map.put("id <> " + logged.getDetailId(), " AND ");
            map.put("id_usuario = " + getId_usuario().toString(), " AND ");
            map.put("id_gps  = " + getId_gps().toString(), " ");

            //Verifica si el registro existe, de lo contrario lo inserta
            if (user_allocantionlFind.byExist(map)) {
                throw new Exc("m5");
            }

            sql = "UPDATE public.usuario_gps SET "
                    + "id_gps = " + getId_gps() + ", "
                    + "id_usuario = " + getId_usuario() + " "
                    + " WHERE id =" + logged.getDetailId();

            //Actualiza la información del registro
            persistencia.executeUpdate(sql);

            throw new Exc("m2");

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void delete() {
        try {

            //Verifica si hay registros seleccionados
            if (logged.getMasterId() == 0) {
                throw new Exc("m4");
            }

            //Elimina el resgistro por el id_persona
            deleteById(logged.getMasterId());

            throw new Exc("m3");

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void deleteById(int id) throws Exc, SQLException, Exception {
        //Verifica si el usuario ya existe para otra persona
        sql = "DELETE FROM public.usuario_gps "
                + "WHERE id = " + id;
        persistencia.executeUpdate(sql);
    }

    public void selectedId_usuario(ValueChangeEvent event) {
        setId_usuario(Integer.parseInt(event.getNewValue().toString()));
        // logged.setTempId(getId_usuario());
    }

    public List<Beans> listTable() {

        if (this.logged.getMasterId() != 0) {
            try {
                beansList = new ArrayList<>();
                tableList.clear();
                getChecked().clear();
                int listIndex = 0;

                /*Selecciona todos los gps que tiene la el usuario */
                sql = " select ug.id as id,ug.id_gps,ug.id_usuario,"
                        + "g.imei as imei,g.nombre as nombre,g.caducidad as caducidad, "
                        + "u.usuario as usuario,com.nombre as com_nombre,CURRENT_DATE as actual"
                        + " from  v_usuario_gps ug"
                        + " inner join usuarios u "
                        + " on (ug.id_usuario=u.id) "
                        + " inner join gps g "
                        + " on (ug.id_gps=g.id) "
                        + " inner join public.v_compania com on (com.id=u.id_compania)    "
                        + " where  id_usuario = " + this.logged.getMasterId();

                listIndex = fillTableList(sql, listIndex);

// selecciona los gps que no se han an asignado a un usuario aun 
                sql = "  select  gps.id,gps.imei,gps.nombre,ug.id as usuario ,com.nombre as com_nombre,"
                        + "gps.caducidad ,CURRENT_DATE as actual"
                        + " from public.v_gps gps "
                        + " inner join public.v_compania_gps cps on (cps.id_gps=gps.id)"
                        + "    inner join public.v_compania com on (com.id=cps.id_compania)  "
                        + "  left  join public.v_usuario_gps ug on  (ug.id_gps=gps.id and ug.id_usuario=" + this.logged.getMasterId() + ") "
                        + " where gps.id not in (SELECT id_gps FROM public.v_usuario_gps )"
                        + "  and cps.id_compania=" + logged.getDetailId();

                fillTableList(sql, listIndex);

                if (tableList.isEmpty()) {
                    return null;
                }

                return tableList;
            } catch (Exception ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    private int fillTableList(String sql, int index) throws Exc, SQLException, SQLException, NamingException, Exception {
        ResultSet rsts = persistencia.executeRsts(sql);
        int listIndex = index;
        boolean check, val;
        Date caducidad = new java.util.Date();
        Date actual = new java.util.Date();

        while (rsts.next()) {
            caducidad = rsts.getDate("caducidad");
            Beans bean = new Beans(
                    rsts.getInt("id"),
                    0,
                    0,
                    rsts.getString("imei"),
                    rsts.getString("nombre"),
                    caducidad,
                    rsts.getString("usuario"),
                    rsts.getString("com_nombre"));
            tableList.add(bean);

            actual = rsts.getDate("actual");
            //verifica si esta asignado a una compañia o no
            if ((bean.getUser_loginBeans().getUsuario() != null) && !bean.getUser_loginBeans().getUsuario().isEmpty()) {
                check = true;
            } else {
                check = false;
            }
            getChecked().put(tableList.get(listIndex).getId(), check);
    dias = ((int) (Math.floor((caducidad.getTime() - actual.getTime()) / (1000 * 60 * 60 * 24))));
            
            if (caducidad.compareTo(actual) <= 0) {
                // aun se puede asignar 
                val = true;
                    getState().put(tableList.get(listIndex).getId(), label.name(namePackage(), "estado1")+" ");
                
                
            } else {
                if (dias >=0 & dias <= 30) {
                    getState().put(tableList.get(listIndex).getId(), label.name(namePackage(), "estado2") + " " + dias);
                }
                else {
                getState().put(tableList.get(listIndex).getId(), label.name(namePackage(), "estado3"));
                }
                val = false;
            }
            
            
            
            
            getCaduca().put(tableList.get(listIndex).getId(), val);
            listIndex++;
        }
        persistencia.dbDisconnect();
        return listIndex;
    }

    public boolean check(String user_name) {
        if (user_name.equals("")) {
            return false;
        } else {
            return true;
        }
    }

    public boolean acceso(boolean cadu) {
        if (logged.getLoggedRol() == 2 | logged.getLoggedRol() == 3) {
            if (cadu == true) {
                return true;
            }
        }
        return false;
    }

    public void clear() {
        logged.setMasterId(0);
        clearBeans();
    }

    public void selectedId_gps(ValueChangeEvent event) {
        setId_gps(Integer.parseInt(event.getNewValue().toString()));
        //   logged.setTempId(getId_gps());
    }

    public String printIt() {

        //Get submit button id
        String buttonId = " ";
        return buttonId;
    }

    public void selectedactivo(ValueChangeEvent event) {
        String valor = event.getClass().toString();
        //   logged.setTempId(getId_gps());
    }

    private String namePackage() {
        Package pack = this.getClass().getPackage();
        return pack.getName();
    }

    public void insertTable() {

        Iterator iterator = getChecked().entrySet().iterator();
        String usuario;
        int row = 0;

        try {
            while (iterator.hasNext()) {
                Map.Entry<Integer, Boolean> mapEntry = (Map.Entry) iterator.next();
                usuario = tableList.get(row).getUser_loginBeans().getUsuario();
                /*si esta desseleccionado y tiene nombre de compañia borralo*/
                if (!mapEntry.getValue() && (usuario != null && !usuario.isEmpty())) {
                    deleteById(tableList.get(row).getId());
                } /*de otro modo si esta seleccionado insertalo*/ else if (mapEntry.getValue() && (usuario == null || usuario.isEmpty())) {
                    sql = "INSERT INTO public.usuario_gps   (id_gps,id_usuario) "
                            + "VALUES (" + mapEntry.getKey() + ","
                            + logged.getMasterId() + ")";

                    //Inserta la información del registro
                    persistencia.executeUpdate(sql);
                }

                row++;
            }
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public Map<Integer, Boolean> getChecked() {
        return checked;
    }

    public void setChecked(Map<Integer, Boolean> checked) {
        this.checked = checked;
    }

    public Map<Integer, Boolean> getCaduca() {
        return caduca;
    }

    public void setCaduca(Map<Integer, Boolean> caduca) {
        this.caduca = caduca;
    }

    public Map<Integer, String> getState() {
        return state;
    }

    public void setState(Map<Integer, String> state) {
        this.state = state;
    }

    /**
     * @return the cant
     */
    public int getCant() {
        cant += 1;
        return cant;
    }

    /**
     * @param cant the cant to set
     */
    public void setCant(int cant) {
        this.cant = cant;
    }
}
